package cn.zorbus.laian.infrastructure.repository;

import cn.hutool.core.collection.CollectionUtil;
import cn.zorbus.laian.domain.entity.SwitchEntity;
import cn.zorbus.laian.domain.repository.ISwitchRepository;
import cn.zorbus.laian.infrastructure.bus.UdpEventBus;
import cn.zorbus.laian.infrastructure.config.SwitchProperties;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
@Repository
public class SwitchRepository implements ISwitchRepository {

    @Resource
    private SwitchProperties properties;

    @Resource
    private UdpEventBus eventBus;

    private static final Map<Integer, SwitchEntity> HASH_MAP = new LinkedHashMap<>();

    public boolean ledClosed(){
        SwitchEntity switchEntity = HASH_MAP.get(15);
        return switchEntity.getStatus() == 0;
    }


    @PostConstruct
    public void init() {
        if (CollectionUtil.isEmpty(HASH_MAP)) {
            properties.getItems().forEach(switchEntity -> HASH_MAP.put(switchEntity.getId(), switchEntity));
        }
    }

    @Override
    public Collection<SwitchEntity> findAll() {
        return HASH_MAP.values().stream().filter(x -> x.getId() >= 10).toList();
    }

    public String switchMain(int id) {
        SwitchEntity switchEntity = HASH_MAP.get(id);
        if (!Objects.isNull(switchEntity)) {
            switchEntity.getControllers().forEach(num -> {
                eventBus.sentEvent("2|" + num + "|" + switchEntity.getStatus());
                sleep();
            });
        }
        extracted(id);
        return "success";
    }

    private static void extracted(int id) {
        switch (id) {
            case 1:
                //一键开馆
                HASH_MAP.values().stream()
                        .filter(x -> List.of(11, 12, 13, 14, 15, 16, 17).contains(x.getId()))
                        .forEach(switchEntity -> switchEntity.setStatus(1));
                break;
            case 2:
                //一键闭馆
                HASH_MAP.values().stream()
                        .filter(x -> List.of(11, 12, 13, 14, 15, 16, 17).contains(x.getId()))
                        .forEach(switchEntity -> switchEntity.setStatus(0));
                break;
            case 3:
                //一键开灯
                HASH_MAP.values().stream()
                        .filter(x -> List.of(11, 12, 13, 14).contains(x.getId()))
                        .forEach(switchEntity -> switchEntity.setStatus(1));
                break;
            case 4:
                //一键关灯
                HASH_MAP.values().stream()
                        .filter(x -> List.of(11, 12, 13, 14).contains(x.getId()))
                        .forEach(switchEntity -> switchEntity.setStatus(0));
                break;
            case 5:
                //一键开屏
                HASH_MAP.values().stream()
                        .filter(x -> List.of(15, 16, 17).contains(x.getId()))
                        .forEach(switchEntity -> switchEntity.setStatus(1));
                break;
            case 6:
                //一键关屏
                HASH_MAP.values().stream()
                        .filter(x -> List.of(15, 16, 17).contains(x.getId()))
                        .forEach(switchEntity -> switchEntity.setStatus(0));
                break;
        }
    }

    @Override
    public String updateStatusById(int id, int status) {
        SwitchEntity switchEntity = HASH_MAP.get(id);
        if (!Objects.isNull(switchEntity)) {
            switchEntity.setStatus(status);
            switchEntity.getControllers().forEach(num -> {
                eventBus.sentEvent("2|" + num + "|" + switchEntity.getStatus());
                sleep();
            });
        }
        return "success";
    }

    @SneakyThrows(InterruptedException.class)
    private void sleep() {
        TimeUnit.MILLISECONDS.sleep(properties.getDelay());
    }
}